#ifndef _LIM_MATRIX
#define _LIM_MATRIX

#include "Matrix.h"

namespace mylib {
	template<class T> class Lim_matrix : private Matrix<T> {
	public:
		Lim_matrix(int __row, int _col, int low, const T &val=T());		// default value is needed
		Lim_matrix(const T *tab);
		~Lim_matrix() {}

		class Out_of_range { };
		class Err_input { };
		class Out_of_mem { };

		// get the element int __row 'r' column 'c'
		T get(int r, int c) { try { return Matrix<T>::get(r, c-_low); }catch(...) {throw Out_of_range();} }
		void put(int __row, int _col, const T &ele) {
			try { Matrix<T>::put(__row, _col-_low, ele); } catch(...) {throw Out_of_range();}
		}
		int row() { return mylib::Matrix<T>::row(); }
		int col() { return mylib::Matrix<T>::col(); }
		const int &low() { return _low; }
		const int &upper(){ return _upper; }
		void write(std::ostream &out){ 
			out << _low << ",\n";			// display the base
			Matrix<T>::write(out); 
		}
		void cmps(){ Matrix<T>::cmps(); }				// compress the matrix
	private:
		Lim_matrix(const Lim_matrix &m){}				// cannot be copied
		Lim_matrix &operator=(const Lim_matrix &m){}
	private :
		int _low, _upper;
	};
}
template<class T> mylib::Lim_matrix<T>::Lim_matrix(int __row, int _col, int low, const T &val):Matrix<T>(__row, _col, val) {
	if( __row <= 0 || _col <= 0 || low < 0 )
		throw Err_input();
	_low = low;
	_upper = low+_col;
}
template<class T> mylib::Lim_matrix<T>::Lim_matrix(const T *tab) : Matrix<T>(tab+1) {
	_low = *tab;
	_upper = _low + *(tab+2);		// _upper = _low+_col
}
#endif
